import { reactive, computed, watch, onBeforeUnmount, getCurrentInstance } from 'vue';
import { saveComplete } from '@/common/api/course.js';
import useSound from '@/common/hooks/useSound.js';
export default function(getContent, keydownFun, resizeFun, initFun) {
	// =================公用工具 start=================
	const { ctx } = getCurrentInstance();
	const { play, stop } = useSound();
	// 页面卸载
	onBeforeUnmount(() => {
		if (init) init();
		uni.$off('reloadCourse');
		uni.$off('nextCourse');
	})
	// 处理分母，如果分母为0，直接返回1
	function denominator(v) {
		return v ? v : 1;
	}
	// 获取节点信息
	function queryRect(el) {
		return new Promise(resolve => {
			ctx.$uv.getRect(`.${el}`).then(size => {
				resolve(size)
			})
		})
	}
	// 刷新数据操作
	function updateData() {
		getApp().globalData.setdzdata('reloadCourseData', 1);
		getApp().globalData.setdzdata('reloadMapData', 1);
		getApp().globalData.setdzdata('reloadChapterData', 1);
	}
	// 键盘音效
	function typingSound(type) {
		if (true) {
			play(type);
		}
	}
	// 游戏音效
	function gameSound(type, loop = false) {
		if (true) {
			play(type, loop);
		}
	}
	// =================公用工具 end=================
	const seting = reactive({
		mode: '', //模式
		isRandom: true, //是否随机
		loopCount: 1, //循环次数
		pronounce: 'uk' //发音方式
	})
	// 打字过程中的数据
	const typing = reactive({
		type: 'BASE',
		content: null,
		allow_mistakes: true,
		current: 0, //当前选中
		record: [],
		kpm: 0, //按键速度
		wpm: 0, //打字速度
		startTime: 0,
		time: 0, //耗时
		timer: 0 //计时器标识
	})
	if (keydownFun) document.addEventListener('keydown', keydownFun);
	if (resizeFun) window.addEventListener('resize', resizeFun);
	// 初始化参数
	function init(type = 1) {
		if (type == 1) {
			document.removeEventListener('keydown', keydownFun);
			if (resizeFun) window.removeEventListener('resize', resizeFun);
		}
		if (type == 2) {
			if (resizeFun) resizeFun();
			if (initFun) initFun();
		}
		typing.timer && clearInterval(typing.timer);
		typing.current = 0;
		typing.record = [];
		typing.kpm = 0;
		typing.wpm = 0;
		typing.startTime = 0;
		typing.time = 0;
		typing.timer = 0;
		if (typeof typing.letterCurrent != 'undefined') typing.letterCurrent = 0;
		if (typeof typing.showInput != 'undefined') typing.showInput = false;
		if (typeof typing.showError != 'undefined') typing.showError = false;
	}
	// 类名
	const itemClassName = computed((index, index2) => {
		return (index, index2) => {
			let className = '';
			const _hasError = checkHasError(index, index2);
			const _lastError = checkLastError(index, index2);
			const _success = checkLastSuccess(index, index2);
			const _hasBack = checkHasBack(index, index2);
			const _lastBack = checkLastBack(index, index2);
			if (_lastError) {
				className = typing.allow_mistakes ? 'error' : '';
			} else if (_success && !_hasError && !_hasBack) {
				className = 'success';
			} else if (_lastBack) {
				className = '';
			} else {
				className = 'warn';
			}
			return className;
		}
	})
	// 字类名
	const wClassName = computed((index) => {
		return index => {
			if (index < typing.current) {
				const typing_record_success_words = typing.record[index].filter((item2, index2) => checkLastSuccess(index, index2));
				const isPass = typing_record_success_words.length == typing.record[index].length;
				return isPass ? 'pass' : 'error';
			} else {
				return '';
			}
		}
	})
	// 是否显示错误类名，目前typing.type=='BASE'+复习才能用到
	const showErrorClass = computed((index) => {
		return index => {
			const _success = checkLastSuccess(index);
			const _back = checkLastBack(index);
			const v1 = !typing.allow_mistakes && typing.current == index && typing.showError;
			const v2 = typing.allow_mistakes && !_back && !_success;
			return v1 || v2;
		}
	})
	// 按键准确率
	const accuracyKey = computed(() => {
		const { completeSuccessKeyCount, completeKeyCount } = getCompleteInfos();
		return Math.round(completeSuccessKeyCount / denominator(completeKeyCount) * 100);
	});
	// 打字准确率
	const accuracyWord = computed(() => {
		const { completeSuccessWordCount, completeWordCount } = getCompleteInfos();
		return Math.round(completeSuccessWordCount / denominator(completeWordCount) * 100);
	});
	// 进度
	const progress = computed(() => {
		return Math.round((typing.current / typing.content.length * 100));
	});
	// 速度记录
	function recordSpeed() {
		const { kpm, wpm, successWpm } = getSpeed();
		typing.kpm = kpm;
		typing.wpm = wpm;
		return {
			kpm,
			wpm,
			successWpm
		}
	}
	/**
	 * 设置打字记录
	 * @param {Object} type 当前按键状态  success - 正确 error - 错误
	 */
	function setTyping(type, text) {
		if (typeof typing.letterCurrent == 'undefined') {
			if (Array.isArray(typing.record[typing.current])) {
				typing.record[typing.current].push({
					type,
					text
				});
			} else {
				typing.record[typing.current] = [{
					type,
					text
				}];
			}
		} else {
			if (Array.isArray(typing.record[typing.current])) {
				if (typing.record[typing.current][typing.letterCurrent]) {
					typing.record[typing.current][typing.letterCurrent].push(type);
				} else {
					typing.record[typing.current][typing.letterCurrent] = [type];
				}
			} else {
				typing.record[typing.current] = [
					[type]
				];
			}
		}
	}
	// 判断索引位置最后一次是否是正确的success
	function checkLastSuccess(index, index2) {
		if (typeof index2 == 'undefined') {
			const typing_record_item = typing.record[index];
			return typing_record_item && typing_record_item[typing_record_item.length - 1]?.type == 'success';
		} else {
			if (typing.record[index] && typing.record[index][index2]) {
				const typing_record_item = typing.record[index][index2];
				return typing_record_item && typing_record_item[typing_record_item.length - 1] == 'success';
			}
		}
	}
	// 判断当前输入位置否有错误历史
	function checkHasError(index, index2) {
		if (typeof index2 == 'undefined') {
			const typing_record_item = typing.record[index];
			return typing_record_item && typing_record_item.filter(item => item.type == 'error').length;
		} else {
			if (typing.record[index] && typing.record[index][index2]) {
				const typing_record_item = typing.record[index][index2];
				return typing_record_item && typing_record_item.filter(item => item == 'error').length;
			}
		}
	}
	// 判断索引位置最后一次是否是正确的error
	function checkLastError(index, index2) {
		if (typeof index2 == 'undefined') {
			const typing_record_item = typing.record[index];
			return typing_record_item && typing_record_item[typing_record_item.length - 1]?.type == 'error';
		} else {
			if (typing.record[index] && typing.record[index][index2]) {
				const typing_record_item = typing.record[index][index2];
				return typing_record_item && typing_record_item[typing_record_item.length - 1] == 'error';
			}
		}
	}
	// 判断当前输入位置否有退格历史
	function checkHasBack(index, index2) {
		if (typeof index2 == 'undefined') {
			let typing_record_item = typing.record[index];
			return typing_record_item && typing_record_item.filter(item => item.type == 'back').length;
		} else {
			if (typing.record[index] && typing.record[index][index2]) {
				let typing_record_item = typing.record[index][index2];
				return typing_record_item && typing_record_item.filter(item => item == 'back').length;
			}
		}
	}
	// 判断索引位置最后一次是否是退格back，如果typing.record[index]不存在也返回true
	function checkLastBack(index, index2) {
		if (typeof index2 == 'undefined') {
			let typing_record_item = typing.record[index];
			const v = typing_record_item && typing_record_item[typing_record_item.length - 1]?.type == 'back';
			return typeof v == 'undefined' ? true : v;
		} else {
			if (typing.record[index] && typing.record[index][index2]) {
				let typing_record_item = typing.record[index][index2];
				return typing_record_item && typing_record_item[typing_record_item.length - 1] == 'back';
			} else {
				return true;
			}
		}
	}
	// 获取无修复正确率
	function getTrueAccuracy() {
		const { completeSuccessKeyNoBackCount, completeKeyCount } = getCompleteInfos();
		return Math.round(completeSuccessKeyNoBackCount / denominator(completeKeyCount) * 100);
	}
	// 获取退格次数
	function getBackCount() {
		let backCount = 0;
		if (seting.mode != 'DOUBLE') {
			typing.record.forEach(item => {
				const backCountArr = item.filter(item2 => item2.type.indexOf('back') > -1);
				backCount += backCountArr.length;
			})
		} else {
			typing.record.forEach(item => {
				const backCountArr = item.filter(item2 => item2.indexOf('back') > -1);
				backCountArr.forEach(item2 => {
					const backCountArr2 = item2.filter(item3 => item3.indexOf('back') > -1);
					backCount += backCountArr2.length;
				})
			})
		}
		return backCount;
	}
	// 获取打字的正确和错误的数据
	function getTypingStats() {
		const keystrokeStats = {};
		if (seting.mode != 'DOUBLE') {
			typing.record.forEach((item, index) => {
				const t = typing.content[index].char || typing.content[index];
				const t_success = keystrokeStats[t] && keystrokeStats[t].success ? keystrokeStats[t].success : 0;
				const t_error = keystrokeStats[t] && keystrokeStats[t].error ? keystrokeStats[t].error : 0;
				keystrokeStats[t] = {
					success: t_success + (checkLastSuccess(index) ? 1 : 0),
					error: t_error + checkHasError(index)
				}
			})
		} else {
			typing.record.forEach((item, index) => {
				item.forEach((item2, index2) => {
					const t = typing.content[index].typing[index2];
					const t_success = keystrokeStats[t] && keystrokeStats[t].success ? keystrokeStats[t].success : 0;
					const t_error = keystrokeStats[t] && keystrokeStats[t].error ? keystrokeStats[t].error : 0;
					keystrokeStats[t] = {
						success: t_success + (checkLastSuccess(index, index2) ? 1 : 0),
						error: t_error + checkHasError(index, index2)
					}
				})
			})
		}
		return keystrokeStats;
	}
	// 获取完成的字符================
	function getComplateStr() {
		let str = '';
		typing.record.forEach(item => {
			const _item = item[item.length - 1];
			if (_item.type != 'back') {
				str += _item.text;
			}
		})
		return str;
	}
	// 获取当前所有完成字母相关信息
	function getCompleteInfos() {
		switch (seting.mode) {
			case 'CNCOPY':
				return CNCOPY();
			case 'DOUBLE':
				return DOUBLE();
			default:
				return DEFAULT();
		}
	}

	function DEFAULT() {
		// ==========计算词的数量 start==========
		let index = 0;
		// 完成词量（不分对错）
		let completeWords = 0;
		// 正确词量
		let successWords = 0;
		// 获取对应课程的单词，每个单词末尾包括一个空格
		const courseContentWords = typing.courseContentStr.split(/(\S+\s*)/).filter(function(e) { return e; });
		courseContentWords.forEach(item => {
			const _item = item.replace(/\n/g, '');
			const completeItem = getComplateStr().substring(index, _item.length + index);
			if (completeItem.length == _item.length) {
				if (_item === completeItem) {
					successWords++;
				}
				completeWords++;
			}
			index += _item.length;
		})
		// ==========计算词的数量 end==========
		const typing_record_complete_arr = typing.record.filter((item, index) => !checkLastBack(index));
		const typing_record_success_arr = typing.record.filter((item, index) => checkLastSuccess(index));
		const typing_record_success_repair_arr = typing_record_success_arr.filter((item, index) => item.find(item2 => item2.type == 'back'));
		const typing_record_success_repair_not_count = typing_record_success_arr.length - typing_record_success_repair_arr.length;
		return {
			completeKeyCount: typing_record_complete_arr.length, //完成键的计数
			completeSuccessKeyCount: typing_record_success_arr.length, //完成正确键的计数
			completeSuccessKeyNoBackCount: typing_record_success_repair_not_count, //完成正确键且无修复的计数
			completeWordCount: completeWords, //完成词的计数
			completeSuccessWordCount: successWords //完成正确词的计数
		}
	}

	function CNCOPY() {
		const typing_record_complete_arr = typing.record.filter((item, index) => !checkLastBack(index));
		const typing_record_success_arr = typing.record.filter((item, index) => checkLastSuccess(index));
		const typing_record_success_repair_arr = typing_record_success_arr.filter((item, index) => item.find(item2 => item2.type == 'back'));
		const typing_record_success_repair_not_count = typing_record_success_arr.length - typing_record_success_repair_arr.length;
		return {
			completeKeyCount: typing_record_complete_arr.length, //完成键的计数
			completeSuccessKeyCount: typing_record_success_arr.length, //完成正确键的计数
			completeSuccessKeyNoBackCount: typing_record_success_repair_not_count, //完成正确键且无修复的计数
			completeWordCount: typing_record_complete_arr.length, //完成键的计数
			completeSuccessWordCount: typing_record_success_arr.length, //完成正确键的计数
		}
	}

	function DOUBLE() {
		// 所有完成的字母
		let typing_record_complete_arr = [];
		// 正确的字母
		let typing_record_success_arr = [];
		// 在正确字母中出现了修正的字母
		let typing_record_success_repair_arr = [];
		// 正确词的个数
		let typing_success_word_count = 0;
		const typing_record_cur = typing.record.filter((item, index) => index <= typing.current);
		typing_record_cur.forEach((item, index) => {
			const typing_record_complete = item.filter((item2, index2) => !checkLastBack(index, index2));
			typing_record_complete_arr = typing_record_complete_arr.concat(typing_record_complete);
			const typing_record_success = item.filter((item2, index2) => checkLastSuccess(index, index2));
			typing_record_success_arr = typing_record_success_arr.concat(typing_record_success);
		})
		typing_record_success_repair_arr = typing_record_success_arr.filter(item => item.find(item2 => item2 == 'back'));
		const typing_record_success_repair_not_count = typing_record_success_arr.length - typing_record_success_repair_arr.length;
		// =====计算完成正确的词 start=====
		const typing_record_complete_words = typing.record.filter((item, index) => index < typing.current);
		typing_record_complete_words.forEach((item, index) => {
			const typing_record_success_words = item.filter((item2, index2) => checkLastSuccess(index, index2));
			if (typing_record_success_words.length == item.length) {
				typing_success_word_count++;
			}
		})
		// =====计算完成正确的词 end=====
		return {
			completeKeyCount: typing_record_complete_arr.length, //完成键的计数
			completeSuccessKeyCount: typing_record_success_arr.length, //完成正确键的计数
			completeSuccessKeyNoBackCount: typing_record_success_repair_not_count, //完成正确键且无修复的计数
			completeWordCount: typing.current, //完成词的计数
			completeSuccessWordCount: typing_success_word_count //完成正确词的计数
		}
	}
	// 计算速度
	function getSpeed() {
		const { completeKeyCount, completeWordCount, completeSuccessWordCount } = getCompleteInfos();
		const curTime = Date.now();
		// 计算打字时间（秒）  
		const typingTimeInSeconds = (curTime - typing.startTime) / 1000;
		// 转换为分钟（如果需要）  
		const typingTimeInMinutes = typingTimeInSeconds / 60;
		// 计算键盘速度（键/分钟）
		const typingSpeedKPM = Math.round(completeKeyCount / typingTimeInMinutes);
		// 计算打字速度（字/分钟）
		const typingSpeedWPM = Math.round(completeWordCount / typingTimeInMinutes);
		// 计算打字正确速度（字/分钟）
		const typingSpeedSuccessWPM = Math.round(completeSuccessWordCount / typingTimeInMinutes);
		switch (seting.mode) {
			case 'CNCOPY':
				return {
					kpm: Math.round(typingSpeedWPM * 1.5), //此处模拟按键速度，是打字速度的2倍
						wpm: typingSpeedWPM,
						successWpm: typingSpeedSuccessWPM
				}
				break;
			default:
				return {
					kpm: typingSpeedKPM,
						wpm: typingSpeedWPM,
						successWpm: typingSpeedSuccessWPM
				}
				break;
		}
	}
	// 当前课程结束
	async function courseComplete(completeRef) {
		typing.timer && clearInterval(typing.timer);
		const { courseId, courseType } = getContent();
		const { kpm, wpm, successWpm } = recordSpeed();
		const characterId = getApp().globalData.dzcharacter?.character?.characterId;
		const params = {
			characterId,
			courseId
		}
		// 只有练习的课程才记录更详细的内容
		if (['LEARN', 'REVIEW', 'GAME'].indexOf(courseType) == -1) {
			if (seting.mode == 'CNCOPY') {
				params.practiceStats = {
					kpm, //按键速度
					wpm, //打字速度
					successWpm, //正确打字速度
					consumingTime: typing.time, //耗时
					accuracyKey: accuracyWord.value, //按键准确率
					accuracyWord: accuracyWord.value, //打字准确率
					accuracyKeyNoBack: getTrueAccuracy(), //无修复按键准确率
					backspaceCount: getBackCount() //退格次数
				}
			} else {
				params.keystrokeStats = getTypingStats();
				params.practiceStats = {
					kpm, //按键速度
					wpm, //打字速度
					successWpm, //正确打字速度
					consumingTime: typing.time, //耗时
					accuracyKey: accuracyKey.value, //按键准确率
					accuracyWord: accuracyWord.value, //打字准确率
					accuracyKeyNoBack: getTrueAccuracy(), //无修复按键准确率
					backspaceCount: getBackCount() //退格次数
				}
			}
		}
		const { data } = await saveComplete(params);
		completeRef.open(data);
		updateData();
	}
	// 再来一次
	function againCourse() {
		uni.$once('reloadCourse', () => {
			if (init) init(2);
			againCourse();
		})
	}
	// 继续下节课
	function nextCourse() {
		uni.$once('nextCourse', () => {
			const nextCourse = getContent().nextCourse;
			if (!nextCourse?.courseId) return;
			getApp().globalData.setdzdata('courseItem', nextCourse);
			getApp().globalData.setdzdata('lastActive', nextCourse);
			uni.$uv.route({
				url: `/pages/learning/learning`,
				type: 'redirect',
				params: {
					id: nextCourse.courseId
				}
			})
		})
	}
	// 继续下一节课
	function next(item) {
		switch (item.key.toLowerCase()) {
			case 'r':
				uni.$emit('reloadCourse');
				break;
			case 'enter':
				uni.$emit('nextCourse');
				break;
		}
	}
	againCourse();
	nextCourse();
	return {
		seting,
		typing,
		setTyping,
		recordSpeed,
		itemClassName,
		wClassName,
		showErrorClass,
		accuracyKey,
		accuracyWord,
		progress,
		courseComplete,
		queryRect,
		next,
		typingSound,
		gameSound,
		stopSound: stop
	}
}